using ETask.Api.Data;
using ETask.Api.Dtos;
using ETask.Api.Mappers;
using ETask.Api.Models;
using ETask.Api.Repositories;
using Microsoft.AspNetCore.Http;
using System.Text.Json;

namespace ETask.Api.Services
{
    /// <summary>
    /// 审计日志服务实现
    /// </summary>
    public class AuditLogService : GenericService<AuditLog,AuditLogDto,CreateAuditLogDto,UpdateAuditLogDto>, IAuditLogService
    {
        private readonly IAuditLogRepository _auditLogRepository;
        private readonly IHttpContextAccessor _httpContextAccessor;

        public AuditLogService(IAuditLogRepository auditLogRepository, IHttpContextAccessor httpContextAccessor,
            GenericMapper<AuditLog,AuditLogDto,CreateAuditLogDto,UpdateAuditLogDto> mapper) 
            : base(auditLogRepository,mapper)
        {
            _auditLogRepository = auditLogRepository;
            _httpContextAccessor = httpContextAccessor;
        }

        /// <summary>
        /// 分页查询审计日志
        /// </summary>
        public async Task<PagedResult<AuditLogDto>> GetPagedListAsync(AuditLogQueryParams queryParams)
        {
            return await _auditLogRepository.GetPagedListAsync(queryParams);
        }

        /// <summary>
        /// 根据用户ID获取最近的日志
        /// </summary>
        public async Task<List<AuditLogDto>> GetRecentLogsByUserIdAsync(int userId, int count = 10)
        {
            return await _auditLogRepository.GetRecentLogsByUserIdAsync(userId, count);
        }

        /// <summary>
        /// 记录审计日志
        /// </summary>
        public async Task LogAsync(CreateAuditLogDto logDto, int userId, string userName, string account, string? clientIp = null, string? userAgent = null)
        {
            var auditLog = new AuditLog
            {
                ActionType = logDto.ActionType,
                Module = logDto.Module,
                Description = logDto.Description,
                UserId = userId,
                UserName = userName,
                Account = account,
                TargetId = logDto.TargetId,
                TargetName = logDto.TargetName,
                OldValues = logDto.OldValues,
                NewValues = logDto.NewValues,
                Result = logDto.Result,
                ErrorMessage = logDto.ErrorMessage,
                ActionTime = DateTime.Now,
                ClientIp = clientIp ?? GetClientIp(),
                UserAgent = userAgent ?? GetUserAgent(),
                CreateBy = userId,
                UpdateBy = userId
            };

            await _auditLogRepository.AddAsync(auditLog);
        }

        /// <summary>
        /// 记录成功操作日志
        /// </summary>
        public async Task LogSuccessAsync(string actionType, string module, string description, int? targetId = null, string? targetName = null, string? oldValues = null, string? newValues = null)
        {
            var currentUser = UserContext.CurrentUser;
            if (currentUser == null) return;

            var logDto = new CreateAuditLogDto
            {
                ActionType = actionType,
                Module = module,
                Description = description,
                TargetId = targetId,
                TargetName = targetName,
                OldValues = oldValues,
                NewValues = newValues,
                Result = "成功"
            };

            await LogAsync(logDto, currentUser.Id, currentUser.Name, currentUser.Account);
        }

        /// <summary>
        /// 记录失败操作日志
        /// </summary>
        public async Task LogErrorAsync(string actionType, string module, string description, string errorMessage, int? targetId = null, string? targetName = null)
        {
            var currentUser = UserContext.CurrentUser;
            if (currentUser == null) return;

            var logDto = new CreateAuditLogDto
            {
                ActionType = actionType,
                Module = module,
                Description = description,
                TargetId = targetId,
                TargetName = targetName,
                Result = "失败",
                ErrorMessage = errorMessage
            };

            await LogAsync(logDto, currentUser.Id, currentUser.Name, currentUser.Account);
        }

        /// <summary>
        /// 获取客户端IP地址
        /// </summary>
        private string? GetClientIp()
        {
            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext == null) return null;

            // 尝试从X-Forwarded-For头获取真实IP
            var forwardedFor = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
            if (!string.IsNullOrEmpty(forwardedFor))
            {
                return forwardedFor.Split(',')[0].Trim();
            }

            // 尝试从X-Real-IP头获取
            var realIp = httpContext.Request.Headers["X-Real-IP"].FirstOrDefault();
            if (!string.IsNullOrEmpty(realIp))
            {
                return realIp;
            }

            // 使用连接远程IP
            return httpContext.Connection.RemoteIpAddress?.ToString();
        }

        /// <summary>
        /// 获取用户代理
        /// </summary>
        private string? GetUserAgent()
        {
            var httpContext = _httpContextAccessor.HttpContext;
            return httpContext?.Request.Headers["User-Agent"].FirstOrDefault();
        }
    }
}
